home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / byt0187b.arc / ZAPAL.C < prev   
C/C++ Source or Header  |  1980-01-02  |  23KB  |  715 lines

  1.  
  2. /*      ZAPAL.C - Byte Magazine ZAP-A-PAL Programmer for IBM-PC        */
  3.  
  4. /*    Version 2.0 - by Robert A. Freedman - 24 Dec 1986 - 3:00 AM    */
  5.  
  6. /* COPYRIGHT Notice: (C) 1986 by Robert A. Freedman. All RIGHTS Reserved,
  7. A limited license is granted to each reader of Byte Magazine to copy this
  8. program for private use in conjunction with the construction of a single unit
  9. of the ZAP-A-PAL programmer board described in the January 1987 issue of Byte
  10. Magazine, provided that this notice is included in any copy made.
  11. Commercial resale or distribution of this program is expressely prohibited
  12. without written permission of the author.
  13.  
  14.     Note:    This is NOT Public Domain Software.            */
  15.  
  16. /* This version of ZAPAL is set up to take JEDEC files for PALs which use the
  17. whole fuse array, like 16L8 etc. Sparse array PALs like the 10L8, 14H4, etc. can
  18. be programmed, but you have to edit the JEDEC fuse file to put in the phantom
  19. fuses that most logic compilers leave out in a misguided attempt at efficiency.
  20. To see what the JEDEC file should look like, put a blank sparse PAL into the
  21. socket and (R)ead it into the buffer. Then look at the fuse array with (Y).
  22. The phantom fuses appear as blown. Those columns should be edited into the
  23. JEDEC file produced by the Logic compiler before being loaded into ZAPAL.
  24. You then have to correct the fuze numbers in the JEDEC file to conform to the
  25. full fuse array after editing. Phantom rows are normally supplied by ZAPAL.
  26. The diagrams for sparse array PALs in the PAL Handbook show this clearly.
  27. Don't worry that editing the JEDEC file will blow the checksum. ZAPAL doesn't
  28. bother to verify the checksum in the JEDEC file anyway. Later versions of ZAPAL
  29. will tweek the fusemap for sparse PALs for you, but hey, I had to leave
  30. something to challenge the hobbiest. It'd be no fun if I did everything for you.
  31. Besides, if you stick with 16L8, 16R4-6-8, 20L8, etc. like I do, ZAPAL works OK.
  32. Another thing to watch is that your logic compiler produces the proper polarity
  33. for true output PALs like 14H4 or 10H8. You may have to invert the sense of the
  34. fuse in this program if it is incorrect. If there is enough interest, I will
  35. make updated versions of ZAPAL available for Byte to distribute as the program
  36. develops.
  37.  
  38.     Any questions or comments?
  39.  
  40. Bob Freedman, PO Box 1348, Lawrence, Mass. 01842. (617) 683-4659
  41. */
  42.  
  43. #include <stdio.h>
  44.  
  45. #define uchar unsigned char
  46. #define ERROR -1
  47. #define base  0x100    /* Zap-A-PAL Address Space is from 100 -> 10F hex */
  48. #define DAC_A base+0
  49. #define DAC_B base+1
  50. #define SCLK  base+2
  51.  
  52. #define STROBE base+0x8
  53. #define ENAB   base+0x9        /* Enable BiMOS drivers    */
  54. #define ENCH   base+0xA
  55. #define ENCL   base+0xB
  56. #define VLH    base+0xD
  57. #define VINHIB base+0xE
  58. #define TRIG   base+0xF
  59.  
  60. #define BUSY        (~inportb(base+0xC) & 1)
  61.         /*     (inportb(base+0xC) ^ 1) & 1    */
  62. #define CAL_REF_10V       inportb(base+0xA) & 1
  63. #define    CAL_REF_2P5       inportb(base+0xB) & 1
  64. #define P23 base+0x8
  65. #define P22 base+0x0
  66. #define P21 base+0x1
  67. #define P20 base+0x2
  68. #define P19 base+0x3
  69. #define P18 base+0x4
  70. #define P17 base+0x5
  71. #define P16 base+0x6
  72. #define P15 base+0x7
  73. #define P14 base+0x9
  74.  
  75. int c,e;
  76. static float slope_a,slope_b,vcc_want,ver_want,vihh_want;
  77.  
  78. static int vcclo,vcchi,vihlo,vihhi;    /* Auto-Cal Points    */
  79.        int dac,dac_vcc,dac_vihh;
  80.        int vcc,ver,verlo,verhi,vihh;    /* DAC settings        */    
  81.  
  82. static float  actual_10V = 10.110 ;    /* Measured values of    */
  83. static float  actual_2P5 =  2.463 ;    /* Voltage References    */
  84.  
  85. static float  vcc_offset = 0.000+0.7 ;    /* Compensate for diode drops    */
  86. static float vihh_offset = 1.130+0.7 ;    /* in Drivers & at GND Pin    */
  87.  
  88. static int verpin,vad,fuse;    /* Pin # to verify, I/O adr, State    */
  89. static int veradr[10] = {9,7,6,5,4,3,2,1,0,8};    /* Mux adr for Pins 14 - 23 */
  90.  
  91. uchar pins[32];
  92. /*        Outputs         Control        Inputs
  93.      2 2 2 1 1 1 1 1 2 1    1                              1 1
  94.          2 1 0 9 8 7 6 5 3 4  1 3              2 3 4 5 6 7 8 9 0 1    */
  95. static uchar clear[28] =
  96.     {0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; /* Clear */
  97. static uchar odlo[28] =
  98.     {0,0,0,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; /* OD lo */
  99. static uchar odhi[28] =
  100.     {0,0,0,0,0,0,0,0,0,0, 1,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0}; /* OD hi */
  101.  
  102. static int pind[24] =    /* Maps Pin numbers to Shift Register Position    */
  103.     {10,18,19,20,21,22,23,24,25,26,27,28,11,9,7,6,5,4,3,2,1,0,8};
  104.  
  105. static s;        /* s is Style of fuze-map print-out    */
  106.  
  107. int cksum;    /* Check-Sum for JEDEC file    */
  108. int devno;    /* 'D'nnnn read from Basic JEDEC file    */
  109.  
  110. struct    mfg_attr {
  111. char    *mfg_nam;
  112. float    verlo,verhi,vihh; } m[] = {
  113.  
  114. { {" MMI"},        5.0, 5.5, 11.75 },
  115. { {"-B MMI"},        6.0, 6.0, 10.00 },
  116. { {" TI "},        5.0, 5.0, 10.50 },
  117. { {" NSC"},        5.0, 5.5, 11.75 }
  118. };
  119.  
  120. int ci,chip_index;
  121. int mi,mfg_index;
  122.  
  123. struct    chip_type {
  124. char    *chip_nam;
  125. int    npins,fuzes; } t[] = {
  126.  
  127. { {"16L8"},        20, 2048 },
  128. { {"16R8"},        20, 2048 },
  129. { {"16R6"},        20, 2048 },
  130. { {"16R4"},        20, 2048 },
  131. { {"10H8"},        20, 2048 },
  132. { {"10L8"},        20, 2048 },
  133. { {"12H6"},        20, 2048 },
  134. { {"12L6"},        20, 2048 },
  135. { {"14H4"},        20, 2048 },
  136. { {"14L4"},        20, 2048 },
  137. { {"16H2"},        20, 2048 },
  138. { {"16L2"},        20, 2048 },
  139. { {"16C1"},        20, 2048 },
  140. { {"16X4"},        20, 2048 },
  141. { {"16A4"},        20, 2048 },
  142. { {"12L10"},        24, 3200 },
  143. { {"14L8"},        24, 3200 },
  144. { {"16L6"},        24, 3200 },
  145. { {"18L4"},        24, 3200 },
  146. { {"20L2"},        24, 3200 },
  147. { {"20C1"},        24, 3200 },
  148. { {"20L10"},        24, 3200 },
  149. { {"20X10"},        24, 3200 },
  150. { {"20X8"},        24, 3200 },
  151. { {"20X4"},        24, 3200 },
  152. { {"20L8"},        24, 3200 },
  153. { {"20R8"},        24, 3200 },
  154. { {"20R6"},        24, 3200 },
  155. { {"20R4"},        24, 3200 }
  156. };
  157.  
  158. unsigned seg,offset,off,word;
  159. struct regval { int ax,bx,cx,dx,si,di,ds,es; };
  160. struct regval *sreg,*rreg;
  161.  
  162. int     n,n_wr,i,j,sum,lr,ix,ino,af,T20,T24,fuzno,max;
  163. char    *fn,filename[64],*p,fin[32],fon[32];
  164.  
  165. extern FILE *fopen();
  166. FILE    *fo,*fp;
  167.  
  168. static int fuzmap[4096];
  169.  
  170. int test_fuz;    /* for TEST program    */
  171.  
  172. main(argc,argv) int argc; char **argv;
  173. {
  174.     strcpy(fin,"file.jed");    /* Init Dummy file.names    */
  175.     strcpy(fon,"fmap.jed");
  176.  
  177.     T20 = 1;    /* Do 20-pin PALs    */
  178.     ci = mi = 0;    test_fuz = 0;    s = 5;
  179.  
  180. /*    dac_vcc  = 131;    */    /* DAC-A 131 = 5.02 Volts    */
  181. /*    dac_vihh = 154;    */    /* DAC-B 154 = 11.75 Volts: 13.00 @ VIHH */
  182.  
  183.     autocal(0);    shutdn();
  184.  
  185.     menu();        shutdn();    exit(0); 
  186.  }
  187. menu()        /* Display List of ZAPAL Commands    */
  188. {
  189. int szct,szmt;    /* number of entries in structures.    */
  190.  
  191. uchar *b; b="                                        ";
  192.     wipe();    /* Clear Screen    */
  193.         szct = sizeof(t) / sizeof(struct chip_type);
  194.         szmt = sizeof(m) / sizeof(struct  mfg_attr);
  195.  
  196.     while ( 1 ) {
  197.  
  198.      crt_srcp(0,0,0);    printf(
  199. "\tZAP-A-PAL Programmer - (C) 1986 by R. A. Freedman S# 00001        ");
  200.     T20 = ( t[ci].npins==20 ? 1 : 0 );
  201.     printf("\n\n\t\t%PAL-%s %s has %2d pins and %4d fuzes        \n",
  202.         t[ci].chip_nam,m[mi].mfg_nam,t[ci].npins,t[ci].fuzes );
  203.  
  204.     printf("\n\tT - Select Device Type:");
  205.     printf("\n\tU - Select Chip Manufacturer:");
  206.     printf("\n\tL - Load PAL chip into RAM");
  207.     printf("\n\tR - Show fuze map from PAL Chip");
  208.     printf("\n\tY - Show fuze map from RAM");
  209.     printf("\n\tC - Compare PAL chip with RAM");
  210.     printf("\n\tZ - Burn  a PAL from RAM");
  211.     printf("\n\tV - Verify  PAL against RAM");
  212.     printf("\n\tI - Set to READ  file %s        ",fin);
  213.     printf("\n\tO - Set to WRITE file %s        ",fon);
  214.     printf("\n\tJ - Load  JEDEC file into RAM *");
  215.     printf("\n\tW - Write JEDEC file from RAM");
  216.     printf("\n\tS - Style of Fuze MAP is %s ",(s&1?"JEDEC":"PALASM"));
  217.     printf("\n\tF - FUZEs are shown as %s",(s&2?"'1' or '0'":"'X' or '-'"));
  218.     printf("\n\tG - %s GAP every 4th fuse",(s&4?"Insert":"Don't "));
  219. /*    printf("\n\tM - Calibrate manually");    */
  220.     printf("\n\tA - Auto-Calibrate");
  221.     printf("\n\tQ - Quit to DOS \t\t");
  222.     printf("\n%s%s%s%s%s%s",b,b,b,b,b,b);     crt_srcp(21,0,0);
  223.  
  224.  
  225.         c = tolower(bdos(1) & 0xFF);    /* Read a Key    */
  226.         switch(c) {
  227.  
  228.         case 'm': calib();    break;
  229.         case 'a': autocal(1);    break;
  230.         case 'q': return(0);    break;
  231.         case 'r': shopal(1,s);    break;    /* Show Fuz-Map from chip */
  232.         case 'y': shopal(0,s);    break;    /* show Fuz-Map from RAM  */
  233.         case 'e': test();    break;
  234.         case 'z': zapal();    break;
  235.         case 'v': mount(); veripal();    break;
  236.         case 'l': loadpal();    break;
  237.         case 'j': if(loadjedec()==ERROR){
  238.                 printf("ERROR"); getchar(); }; break;
  239.         case 'w': write_jedec();    break;
  240.         case 'p': paltype();    break;
  241.         case 'c': shopal(2,s);    break;    /* Compare PAL with RAM    */
  242.         case 's': s = s ^ 1;    break;
  243.         case 'f': s = s ^ 2;    break;
  244.         case 'g': s = s ^ 4;    break;
  245.         case 't': ci= (ci+1) % szct;    break;
  246.         case 'u': mi= (mi+1) % szmt;    break;
  247.         case 'i': getfn(fin);    break;
  248.         case 'o': getfn(fon);    break;
  249.         case 's': s = s ^ 1;    break;
  250.  
  251.         default :        break;
  252.         }; shutdn();
  253.  
  254.     };
  255. }
  256. getfn(fn) char *fn;    /* Get a file name    */
  257. {char *p; int l;
  258.         printf(" Enter File.nam ");
  259.         fgets(fn,30,stdin); l=strlen(fn);
  260.         p = fn + l - 1;  *p = 0; /* zot \n    */
  261. }
  262. wipe()
  263. {
  264.     printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  265. }
  266. paltype(){}
  267. loadjedec()    /* Load a JEDEC file into RAM    */
  268. {
  269.     fp = fopen(fin,"r");
  270.         if (!fp) { erra(fp,"\nCan't OPEN file ",fin); return(0); };
  271.  
  272.     for (fuzno=0; fuzno < (T20?2048:3200); fuzno++) {
  273.         fuzmap[fuzno] = 2;    /* Mark as Empty    */
  274.     };
  275.  
  276.     if (star() == ERROR) return(ERROR);    /* scan for '*'    */
  277.  
  278.     while (1) {
  279.     
  280.         if (white() == ERROR) return(ERROR);
  281.  
  282.         /* c must have command letter, Q G F L C #    */
  283.  
  284.         if (c == 'Q') { c = fgetc(fp);
  285.             if (c == 'P')    /* max # of pins on chip   */
  286.                     {                };
  287.             if (c == 'F')    /* max # of fuses in array */
  288.                     {                };
  289.             if (star() == ERROR) return(ERROR); /* scan for '*' */
  290.             continue;
  291.         };
  292.  
  293.         if (c == 'G')    /* State of Security Fuze    */
  294.                 { fgetc(fp); };
  295.  
  296.         if (c == 'F')    /* Default for undefined fuses    */
  297.                 { fgetc(fp); };
  298.  
  299.         if (c == 'C')   /*   CheckSum    */
  300.                 { fclose(fp); return(0); };
  301.  
  302.         if (c == 03)   /*   other kind of CheckSum    */
  303.                 { fclose(fp); return(0); };
  304.  
  305.         if (c == 'D') {
  306.             devno = 0; for (i=0;i<4;i++) { c = fgetc(fp);
  307.                 devno = devno * 10 + ani(c);    }; };
  308.  
  309.         if (c == 'L') {
  310.             fuzno = 0; for (i=0;i<4;i++) { c = fgetc(fp);
  311.                 fuzno = fuzno * 10 + ani(c);    };
  312.  
  313.             while ( (c=white()) == '1' || c == '0')
  314.                 { fuzmap[fuzno] = c & 1; fuzno++; };
  315.         };
  316.     };
  317. }
  318. white()    /* eat chars till c is no longer whitespace    */
  319. {        do {    if ((c=fgetc(fp))==ERROR) { fclose(fp);
  320.                 erra(c,"while eating white-space","");
  321.                 return(ERROR); };
  322.         } while ( isspace(c) ); return(c);
  323. }
  324. star()    /* Scan til you find an '*' */
  325. {    while ( (c=fgetc(fp)) != '*') {
  326.             if (c==ERROR) { fclose(fp);
  327.             erra(c,"looking for '*'",""); return(ERROR); };
  328.     }; return(c);
  329. }
  330. write_jedec()    /* Write Fuze-Map to disk in JEDEC Format    */
  331. {
  332.     int f;
  333.     fp = fopen(fon,"w");
  334.         if (!fp) { erra(fp,"\nCan't OPEN file ",fon); return(0); };
  335.  
  336.     for (j=0;j<(T20?2048:3200);j++) {
  337.         f = fuzmap[j];
  338.  
  339.         if ( j % (T20?32:40) == 0 ) {
  340.              if (f == 2) { j = j + (T20?32:40) - 1; continue; }; 
  341.              fprintf (fp,"\n*L%04d ",j);
  342.         };
  343.  
  344.         fprintf(fp,"%c",( (f & 1) ? '1':'0') );
  345.     };    fprintf(fp,"\n*C%04d\n",cksum);
  346.         fclose (fp);
  347. }
  348. char bcda(p) char *p; {return(ani(*p++)*16+ani(*p++)); }
  349. int ani(c) char c; { return( c >= 'A' ? (c-'7') : (c-'0') ); }
  350.  
  351. loadpal()    /* Load from PAL chip into RAM    */
  352. {
  353.     mount();  max = (T20?2048:3200);
  354.     for (fuzno=0; fuzno < max; fuzno++) {
  355.         if(fuzno%256 == 0) printf("\rLoading %3d %%",percent(fuzno,max) );
  356.         fuzmap[fuzno] = (~readfuz( fuzno )) & 1;
  357.     }; shutdn();
  358. }
  359. mount()
  360. {    printf("\nPlease mount PAL in Zif Socket, Watch Pin 1");
  361.         getchar();
  362.         revup();    /* Turn ON the Power    */
  363. }
  364. shopal(f,s) int f,s;
  365. /*      f = source:    0 = from RAM
  366.             1 = from PAL chip
  367.             2 = show differences
  368.  
  369.       s =    Style:    0
  370.             1 = JEDEC vs PALASM numbering
  371.       bits        2 = "1" & '0'vs 'X' & `-`
  372.             4 = Space every 4 bits
  373.             8 = Gap every 8 lines        */
  374.             
  375. {    int fooz,fuz,ill,j,m;
  376.  
  377.     if(f != 0) mount(); s = s & 7;
  378.  
  379.     fuzno=0;  while ( fuzno < (T20?2048:3200) ) {
  380.  
  381.         ill = (T20?32:40);
  382.         if (bdos(11) & 0xFF) break;    /* Escape from long listing */
  383.         if( (fuzno/ill)%8 && s&4) printf("\n");
  384.  
  385.         printf ( (s&1?"\n*L%04d ":"\n%4d "),
  386.                     (s&1?fuzno:fuzno/(T20?32:40) ) );
  387.         for (j=0;j<(T20?32:40);j++) {
  388.         f = f & 3; m = (~fuzmap[fuzno]) & 1;
  389.         if(f == 0) { fooz = m; };
  390.         if(f == 1) { fooz = readfuz(fuzno); };
  391.         if(f == 2) { fooz = m ^ readfuz(fuzno); };
  392.  
  393.     printf("%c",(f==2?
  394.             (!fooz ? '.' : (m ? 'O':'U') ):
  395.             (s&2?(fooz?'1':'0'):(fooz?'X':'-') )
  396.             )
  397.         );
  398.             fuzno++;
  399.             if ( !(fuzno % 4) ) printf((s&4?" ":""));
  400.         };
  401.     }; shutdn();    printf("\tHit any key"); key(); wipe();
  402.  
  403. }
  404. autocal(ar) int ar;    /* Automatic Calibration of Voltage Generators    */
  405. {    int d,test;        /* ar =  0: autotmatic    */
  406.     float a;        /* ar = !0: optional    */
  407.  
  408.     outportb(DAC_A,0);    /* Load DAC-A = 0 V    */
  409.     outportb(DAC_B,0);    /* Load DAC-B = 0 V    */
  410.  
  411.     printf("\nPlease Remove PAL from socket during Calibration");
  412.         getchar();
  413.                 /* Turn ON the Power    */
  414.     outportb(ENAB,0);    /* Disable BiMOS drivers     */
  415.     outportb(ENCL,1);    /* Disable BiMOS drivers CLOCK    */
  416.     outportb(ENCH,1);    /* Disable BiMOS drivers OD    */
  417.  
  418.         outportb(VINHIB,1);     /* Turn ON 497 Booster    */
  419.     outportb(VLH,0);    /* Set Booster to Low (15V)    */
  420.     outportb(TRIG,0);    /* Make sure TRIG is low    */
  421.  
  422.     test = 0; d = 0; dac = 0;
  423.  
  424.         vcclo = slew(0,0); if (vcclo == ERROR) return(ERROR);
  425.  
  426.         vcchi = slew(0,1); if (vcchi == ERROR) return(ERROR);
  427.  
  428.         dac--;    slew(0,1);
  429.  
  430.     outportb(DAC_A,0);    /* Load DAC-A = 0 V    */
  431.     outportb(DAC_B,0);    /* Load DAC-B = 0 V    */
  432.  
  433.     dac = 0;printf("\n");
  434.  
  435.         vihlo = slew(1,0); if (vihlo == ERROR) return(ERROR);
  436.  
  437.         vihhi = slew(1,1); if (vihhi == ERROR) return(ERROR);
  438.  
  439.         dac--;slew(1,1);
  440.  
  441.     slope_a = (actual_10V - actual_2P5) / (vcchi - vcclo);
  442.     slope_b = (actual_10V - actual_2P5) / (vihhi - vihlo);
  443.  
  444.     if (!ar) {printf("\nHit ANY key "); key(); return(0); };
  445.     printf("\nSlope_A = %8.4f Slope_B = %8.4f ",slope_a, slope_b);
  446.  
  447.     for ( a=1.0; a <= 16.0; a+=0.5) { vcc_want = a; vihh_want = a;
  448.  
  449.     vcc  = vcclo + ( vcc_want - actual_2P5) / slope_a;
  450.     vihh = vihlo + (vihh_want - actual_2P5) / slope_b;
  451.  
  452.         printf ("\n %4.2f Volts =>  vcc = %4d" ,vcc_want ,vcc);
  453.  
  454.         printf ("   %4.2f Volts => vihh = %4d",vihh_want,vihh);
  455.     }; key(); wipe();
  456.     
  457. }
  458. int slew(d,test) int d,test;    /*    Scan for Thresholds    */
  459. {
  460.     do { if (dac > 255) {
  461.         printf("\nCalibration Failure: DAC-%C off Scale",(d?'B':'A') );
  462.         printf("\nProbable Hardware Failure, or Wrong Port Address.");
  463.         return(ERROR); };
  464.  
  465.         outportb((d?DAC_B:DAC_A),dac);    /* Load DAC-(A or B) */
  466.  
  467.      dac++;} while ( !(test? CAL_REF_10V : CAL_REF_2P5) );
  468.  
  469.         printf("\r%s = %3d @ 2.5Volt Point and %3d @ 10.0V Point %3d",
  470.         (d?"vihh":" vcc"),(d?vihlo:vcclo),(d?vihhi:vcchi),dac ); 
  471.         
  472.     return(--dac);        
  473. }
  474.  
  475. calib()         /* Calibrate Programmable Voltage Sources Manually      */
  476.         /* This is useful for Debugging during construction    */
  477.  
  478. {    int d,dac[2]; d = 0; dac[0] = 0; dac[1] = 0;
  479.  
  480.     printf("\nType 'C' to Calibrate, anything else to use defaults-");
  481.     c = tolower( getchar() ); if (c != 'c' ) return(0);
  482.  
  483.                 /* Turn ON the Power    */
  484.     outportb(ENAB,0);    /* Disable BiMOS drivers     */
  485.     outportb(ENCL,1);    /* Disable BiMOS drivers CLOCK    */
  486.     outportb(ENCH,1);    /* Disable BiMOS drivers OD    */
  487.  
  488.         outportb(VINHIB,1);     /* Turn ON 497 Booster    */
  489.     outportb(VLH,0);    /* Set Booster to Low (15V)    */
  490.     outportb(TRIG,0);    /* Make sure TRIG is low    */
  491.  
  492.     outportb(DAC_A,0);    /* Load DAC-A = 0 V    */
  493.     outportb(DAC_B,0);    /* Load DAC-B = 0 V    */
  494.  
  495.     while (1) {
  496.  
  497.         outportb((d?DAC_B:DAC_A),dac[d]);    /* Load DAC-(A or B) */
  498.  
  499.             printf ( "\rvcc=%4d, vihh=%4d %s  %s  ",dac[0],dac[1],
  500.                     (CAL_REF_2P5 ? "High":" Low"),
  501.                     (CAL_REF_10V ? "High":" Low") );
  502.  
  503.         c = tolower(bdos(1) & 0xFF);    /* Press Key for each step */
  504.  
  505.         if (c=='q' ) {dac_vcc = dac[0]; dac_vihh = dac[1]; break; };
  506.         if (c=='v') { outportb((d?DAC_B:DAC_A),0);
  507.                  d = ++d & 1;    /* Switch to Other DAC    */
  508.                 }; 
  509.         if (c=='u') dac[d] = ++dac[d] & 0xFF;    /* Up    */
  510.          if (c=='d') dac[d] = --dac[d] & 0xFF;    /* Down    */
  511.  
  512.     };
  513. }
  514. revup()        /* Set up DACs and Turn On Power    */
  515. {
  516.     outportb(ENAB,0);    /* Disable BiMOS drivers     */
  517.     outportb(ENCL,1);    /* Disable BiMOS drivers CLOCK    */
  518.     outportb(ENCH,1);    /* Disable BiMOS drivers OD    */
  519.  
  520.         outportb(VINHIB,1);     /* Turn ON 497 Booster    */
  521.     outportb(VLH,0);    /* Set Booster to Low (15V)    */
  522.     outportb(TRIG,0);    /* Make sure TRIG is low    */
  523.  
  524.      vcc_want = m[mi].verlo +  vcc_offset;
  525.      ver_want = m[mi].verhi +  vcc_offset;    
  526.     vihh_want = m[mi].vihh  + vihh_offset;
  527.  
  528.     verlo = vcc  = vcclo + ( vcc_want - actual_2P5) / slope_a;
  529.     verhi = ver  = vcclo + ( ver_want - actual_2P5) / slope_a;
  530.             vihh = vihlo + (vihh_want - actual_2P5) / slope_b;
  531.  
  532.         outportb(DAC_A,vcc);    /* Load DAC-A = vcc Volts    */
  533.  
  534.         outportb(DAC_B,vihh);    /* Load DAC-B = VIHH Volts    */
  535.  
  536. /*    printf ("\nvcc = %3d - vihh = %3d",vcc,vihh);    */
  537. }
  538. shutdn()    /* Turn it all off    */
  539. {
  540.     outportb(ENAB,0);    /* Disable BiMOS drivers     */
  541.     outportb(ENCL,1);    /* Disable BiMOS drivers CLOCK    */
  542.     outportb(ENCH,1);    /* Disable BiMOS drivers OD    */
  543.  
  544.         outportb(VINHIB,0);     /* Turn OFF 497 Booster    */
  545.  
  546.         outportb(DAC_A,0);    /* Load DAC-A  =  0 V    */
  547.  
  548.         outportb(DAC_B,0);    /* Load DAC-B  =  0 V    */
  549.     
  550. }
  551. zapal()     /* Burn a PAL from RAM image    */
  552. {
  553.     mount();
  554.         outportb(DAC_A,verlo);        /* Load DAC-A = vcc Volts    */
  555.     pass(3);    /* Programm Lo    */
  556.         outportb(DAC_A,verhi);        /* Load DAC-A = vcc Volts    */
  557.     pass(2);    /* Programm Hi    */
  558.         outportb(DAC_A,verlo);        /* Load DAC-A = vcc Volts    */
  559.     pass(1);    /* Programm Lo    */
  560.     veripal();    /* Verify    */
  561.     shutdn();
  562. }
  563. pass(n) int n;
  564. {    int m,x;
  565.     printf("\rBurning-%1d  ",n);    
  566.     for (fuzno=0; fuzno <(T20?2048:3200); fuzno++) {
  567.     /*    if (fuzno % (T20?32:40) == 0) printf(".");    */
  568.         m = fuzmap[fuzno] & 3;
  569.         if ( m >= 2) continue;    /* Skip Phantom Fuze    */
  570.         if ( m == 0) continue;    /* Skip Wanted  Fuze    */
  571.         if ( m == 1) {    /* for 16L8 fuze is low if blown    */
  572.             /* Set-up and see if fuze is already blown    */
  573.             x = readfuz(fuzno);    /* Read Fuze State    */
  574.             if (!x) continue;    /* Skip if blown */
  575.         /* All Reprieves Exhausted, Blast Fuze to Oblivion */
  576.             zot();
  577.         }; 
  578.     };    return(0);
  579. }
  580.  
  581. veripal()    /* Verify PAL chip versus RAM    */
  582. {
  583.     for (fuzno=0; fuzno < (T20?2048:3200); fuzno++) {
  584.         if (fuzno%64 == 0) printf("\rVerifying-%4d ",fuzno);    
  585.  
  586.         if( (fuzmap[fuzno] & 1) ^ ((~readfuz(fuzno) & 1)) )
  587.             { shutdn(); erra(fuzno,"Verify FAILed","");
  588.                 return(ERROR); };
  589.     }; shutdn(); printf("\nVerify PASSed");
  590. }
  591. test()    /* Be Caraful with this one */
  592. {    revup();
  593.     while (readfuz(test_fuz) ) { zot(); };
  594.     test_fuz = ++test_fuz & 2048-1;    shutdn();
  595. }
  596. int readfuz(fuzno) int fuzno;    /* Set up to read or write a fuze */
  597. {    int half,pln;        /* Return state of selected fuse  */
  598.     pln = ( fuzno / ( T20 ? 32 : 40 ) );
  599.     if (pln > (T20?63:79) ) return(ERROR);
  600.  
  601.     outportb(ENAB,0);    /* Disable BiMOS drivers     */
  602.     outportb(ENCL,1);    /* Disable BiMOS drivers CLOCK    */
  603.     outportb(ENCH,1);    /* Disable BiMOS drivers OD    */
  604.  
  605.     half = ( T20 ? 32 : 40 );    /* Set OD and CLOCK pins    */
  606.     pin( 1, (pln >= half?1:2) );    pin(13, (pln >= half?2:1) );
  607.  
  608.     (pln >= half ? ldsr(odhi) : ldsr(odlo) );    /* Shift OD & Clock */
  609.  
  610.     outportb(ENCL,0);    /* Enable BiMOS drivers    CLOCK    */
  611.     outportb(ENCH,0);    /* Enable BiMOS drivers    OD    */
  612.  
  613.     selfuz(fuzno);        ldsr(pins);
  614.  
  615.     outportb(ENAB,1);    /* Enable BiMOS drivers        */
  616.  
  617.      return( verifuz() );    /* Return state of addressed fuze    */
  618. }
  619. zot()    /* TRIGger the timing PAL to zap the fuze    */
  620. {        while (  BUSY ) { outportb(TRIG,0); };
  621.         while ( !BUSY ) { outportb(TRIG,1); };
  622.         while (  BUSY ) { outportb(TRIG,0); };
  623.         return(0);
  624. }
  625. int verifuz()    /*    Return state of fuze    */
  626. {
  627.     /* Assume the shift-registers are all set up by selfuz(fuzno)    */
  628.     outportb(ENCL,1);    /* Pulse CLOCK pin by floating    */
  629.     outportb(ENCL,0);    /* CLOCK to Z momentarily    */
  630.  
  631.     vad = veradr[verpin-14] + base;    /* Compute Mux adr of Pin    */
  632.     fuse = inportb(vad) & 1;    /* Read the state of the fuse    */
  633.     return(fuse);            /* 0 = Blown, 1 = Intact fuse    */
  634. }
  635. selfuz(fuzno) int fuzno; /* analyzes fuze-number, and sets up all pins */
  636. {       int an,half,of,ox,lino,pl,pln,i;
  637.  
  638.     half = ( T20 ? 32 : 40 );
  639.  
  640.     ldsr(clear);    /* Clear out old fuze info    */
  641.  
  642.     /*    Compute and place input pins    */
  643.  
  644.     lino =( fuzno % half );
  645.  
  646.     pln = ( fuzno / half );
  647.     if (pln > (T20?63:79) ) return(ERROR);
  648.  
  649.     lr = 0; if   (lino & 2)  lr = 2;        /* Find which half       */
  650.  
  651.         ix = 0; if (!(lino & 1)) ix = 1;        /* Find the state of Pin x */
  652.  
  653.         /* Now find where to put the selected pin, ie [I0..I9]           */
  654.  
  655.         for (i=0;i<10;i++) pin(2+i,2); /* Pull all input pins to VIHH   */
  656.  
  657.     ino = lino / 4; pin(2+ino,ix);    /* Then set Selected pin to TTL  */
  658.  
  659.     /*    Compute and Place Output Pins    */
  660.  
  661.     /*    Set OD and CLOCK pins        */
  662.     pin( 1, (pln >= half?1:2) );    pin(13, (pln >= half?2:1) );
  663.  
  664.         pl = pln; if(pln >= half) pl = pln-half;
  665.         an =  pl % 8;                /* A0..An = pl mod 8    */
  666.         ox = (pl / 8) & (T20?0xF:0x1F);        /* Select Outp Pin to pulse */
  667.         for (i=14;i<=23;i++) { pin(i,0); };     /* Clear all Outputs    */
  668.                
  669.                  af = (T20?16:15 ); of = (T20?22:23 ); 
  670.     if ( pln >= half ) { af = (T20?19:19 ); of = (T20?18:18 ); };
  671.     if ((pln <  half) && !T20 ) an = bitinv(an,4);    
  672.     an = an & (T20? 7 : 0xF );
  673.  
  674.     for ( i = (T20?2:3); i >= 0; i--) {  /* Set Address bits  */
  675.         pin(af+i,( an % 2 ? 2 : 0 ) ); an = an / 2;
  676.     };
  677.     pin(of-ox,4);   /* Set Output Pin to Pulse      */
  678.     verpin = of-ox;    /* Save pin to verify fuse state    */
  679.     pin( (pln < half ? (T20?15:14) : (T20?22:23) ),lr); /* Set L/R    */
  680.     /* Now all the pins are set up for programming or verification    */
  681. }
  682. int pin(n,val) int n,val;       /* Read or Store value of a pin */
  683. {int v; uchar *p;       if (n == 0 || n > 24 ) val = 0xE;
  684.             p = pins + *(pind + n - 1 );
  685.             v = *p; *p = val; return(v);
  686. }
  687. shopin()
  688. {    printf("\n");
  689.     for (i=0;i<28;i++) {    if( i == 10 || i == 18 ) printf(" -");
  690.              if( i ==  4 || i ==  8 || i == 23 ) printf(" " );
  691.         printf (" %1x",pins[i] & 0xF ); };
  692. }
  693. copin(p) uchar *p;
  694. {    int i; for (i=0;i<28;i++) { pins[i] = p[i]; };  }
  695.  
  696. ldsr(p) char *p;        /* Load pins into Hardware Shift Register    */
  697. {    int i; i=27; while ( i >= 0 ) { outportb(SCLK,p[i--] ); };
  698.         outportb(STROBE,1) ;    /* Strobe all bits into BiMOS latches    */
  699.         outportb(STROBE,0) ;
  700. }
  701. int bitinv(val,bits) int val,bits;      /* Invert n bits of val */
  702. {       int res; res = 0;
  703.     while (bits) { res = res + res + (val % 2); val = val / 2; bits--;
  704.     };  return(res);
  705. }
  706. int percent(n,max) int n,max;
  707. {    float nn,maxx; nn=n; maxx=max;    return(nn*100.0/maxx);    }
  708. key() /* Hit ANY key    */
  709. {    uchar c; c = tolower(bdos(1) & 0xFF); return(c);
  710. }
  711. erra(e,p,q) int e; char *p,*q;
  712. {    printf("\rERROR: %d %s%s, Hit CR ",e,p,q); while ( getchar() != '\n') {};
  713. }
  714. /*            That's All Folks    -    R.A.F.            */
  715.